{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import annotations\n",
    "\n",
    "import math\n",
    "\n",
    "import ipywidgets as widgets\n",
    "import numpy as np\n",
    "import rerun as rr\n",
    "import rerun.blueprint as rrb\n",
    "from IPython.display import display  # noqa: A004 (makes mypy happy with display calls)\n",
    "from rerun.notebook import Viewer, ViewerEvent\n",
    "from rerun.utilities import build_color_grid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# To show something interesting, we first need to log some data.\n",
    "rr.init(\"rerun_example_callbacks\")\n",
    "\n",
    "# This will output a cube grid of points. We'll be able to select\n",
    "# either the entire grid, or individual points.\n",
    "STEPS = 100\n",
    "twists = math.pi * np.sin(np.linspace(0, math.tau, STEPS)) / 4\n",
    "for t in range(STEPS):\n",
    "    rr.set_time(\"step\", sequence=t)\n",
    "    cube = build_color_grid(10, 10, 10, twist=twists[t])\n",
    "    rr.log(\"cube\", rr.Points3D(cube.positions, colors=cube.colors, radii=0.5))\n",
    "\n",
    "rr.send_blueprint(rrb.Blueprint(rrb.Spatial3DView(name=\"Everything\")))\n",
    "\n",
    "\n",
    "# Spawn a viewer, and create some labels to display the values we're tracking\n",
    "viewer = Viewer()\n",
    "labels = widgets.VBox([\n",
    "    widgets.Label(),  # active timeline\n",
    "    widgets.Label(),  # current time\n",
    "    widgets.Label(),  # viewer selection\n",
    "])\n",
    "\n",
    "\n",
    "def on_viewer_event(event: ViewerEvent) -> None:\n",
    "    if event.type == \"timeline_change\":\n",
    "        labels.children[0].value = f\"active timeline: {event.timeline}\"\n",
    "        labels.children[1].value = f\"current time: {event.time}\"\n",
    "\n",
    "    elif event.type == \"time_update\":\n",
    "        labels.children[1].value = f\"current time: {event.time}\"\n",
    "\n",
    "    elif event.type == \"selection_change\":\n",
    "        # Because it is possible to select multiple items at a time in the Viewer,\n",
    "        # the selection change event yields a list of items.\n",
    "        items = []\n",
    "        for item in event.items:\n",
    "            if item.type == \"entity\":\n",
    "                # Entities always include their entity path, and optionally also:\n",
    "                # * The instance ID\n",
    "                # * The coordinates at which a selection occurred for 2D or 3D views.\n",
    "                #    Coordinates are within the view's space and thus relative to its origin.\n",
    "                # * The view name\n",
    "                entity_path, instance_id, view_name, position = (\n",
    "                    item.entity_path,\n",
    "                    item.instance_id,\n",
    "                    item.view_name,\n",
    "                    item.position,\n",
    "                )\n",
    "                items.append(f\"Entity({entity_path=}, {instance_id=}, {view_name=}, {position=})\")\n",
    "            elif item.type == \"container\":\n",
    "                # Containers and Views include their ID and name.\n",
    "                container_id, container_name = item.container_id, item.container_name\n",
    "                items.append(f\"Container({container_id=}, {container_name=})\")\n",
    "            elif item.type == \"view\":\n",
    "                view_id, view_name = item.view_id, item.view_name\n",
    "                items.append(f\"View({view_id=}, {view_name=})\")\n",
    "        labels.children[2].value = f\"selected=[{' '.join(items)}]\"\n",
    "\n",
    "\n",
    "viewer.on_event(on_viewer_event)\n",
    "\n",
    "display(viewer)\n",
    "display(labels)"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
